package com.springboot.cli.utils;

import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.wml.Numbering;
import org.docx4j.wml.P;
import org.docx4j.wml.PPrBase;

import java.math.BigInteger;

/**
 * description:
 *
 * @author huxingjie
 * @date 2023/11/8 10:38
 */
public class TestDocx4jNumber {
    static org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
    static final String initialNumbering = "<w:numbering xmlns:ve=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\">"
            + "<w:abstractNum w:abstractNumId=\"0\">"
            + "<w:nsid w:val=\"2DD860C0\"/>"
            + "<w:multiLevelType w:val=\"multilevel\"/>"
            + "<w:tmpl w:val=\"0409001D\"/>"
            + "<w:lvl w:ilvl=\"0\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"decimal\"/>"
            + "<w:lvlText w:val=\"%1)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"360\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"1\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerLetter\"/>"
            + "<w:lvlText w:val=\"%2)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"720\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"2\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerRoman\"/>"
            + "<w:lvlText w:val=\"%3)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"1080\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"3\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"decimal\"/>"
            + "<w:lvlText w:val=\"(%4)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"1440\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"4\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerLetter\"/>"
            + "<w:lvlText w:val=\"(%5)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"1800\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"5\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerRoman\"/>"
            + "<w:lvlText w:val=\"(%6)\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"2160\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"6\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"decimal\"/>"
            + "<w:lvlText w:val=\"%7.\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"2520\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"7\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerLetter\"/>"
            + "<w:lvlText w:val=\"%8.\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"2880\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "<w:lvl w:ilvl=\"8\">"
            + "<w:start w:val=\"1\"/>"
            + "<w:numFmt w:val=\"lowerRoman\"/>"
            + "<w:lvlText w:val=\"%9.\"/>"
            + "<w:lvlJc w:val=\"left\"/>"
            + "<w:pPr>"
            + "<w:ind w:left=\"3240\" w:hanging=\"360\"/>"
            + "</w:pPr>"
            + "</w:lvl>"
            + "</w:abstractNum>"
            + "<w:num w:numId=\"1\">"
            + "<w:abstractNumId w:val=\"0\"/>"
            + "</w:num>"
            + "</w:numbering>";
    static String filename = "OUT_NumberingRestart.docx";
    public static void main(String[] args) throws Exception {

        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();

        // Add numbering part
        NumberingDefinitionsPart ndp = new NumberingDefinitionsPart();
        MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
        mainDocumentPart.addTargetPart(ndp);
        ndp.setJaxbElement( ndp.unmarshalDefaultNumbering() );
        // ndp.setJaxbElement( (Numbering) XmlUtils.unmarshalString(initialNumbering) );

        // Add some document content
        // mainDocumentPart.addParagraphOfText("Example of restarting numbering");
        mainDocumentPart.addObject(
                createNumberedParagraph(1, 0, "重症监护系统数据库设计" ,1));

        P p = createNumberedParagraph(1, 0, "text on top level" ,2);
        mainDocumentPart.addObject(p);

        mainDocumentPart.addObject(
                createNumberedParagraph(1, 0, "more text on top level" ,2));
        mainDocumentPart.addObject(
                createNumberedParagraph(1, 0, "more text on top level",2 ));
        mainDocumentPart.addObject(
                createNumberedParagraph(1, 1, "text on level 1" ,2));

        // Ok, lets restart numbering
        long newNumId = ndp.restart(1, 0, 1);

        mainDocumentPart.addObject(
                createNumberedParagraph(newNumId, 0, "text on top level - restarted" ,1));

        // After first using newNumId, it doesn't matter whether
        // subsequent paragraphs use that or the original numId
        mainDocumentPart.addObject(
                createNumberedParagraph(newNumId, 0, "text on top level - using newNumId" ,2));

        mainDocumentPart.addObject(
                createNumberedParagraph(1, 0, "text on top level - using original NumId",2 ));

        // Now save it
        wordMLPackage.save(new java.io.File("d:/" + filename) );

        System.out.println("Done. Saved " + filename);

    }
    private static P createNumberedParagraph(long numId, long ilvl, String paragraphText,int hlevel ) {

        P  p = factory.createP();

        org.docx4j.wml.Text  t = factory.createText();
        t.setValue(paragraphText);

        org.docx4j.wml.R  run = factory.createR();
        run.getContent().add(t);

        p.getContent().add(run);

        org.docx4j.wml.PPr ppr = factory.createPPr();
        //设置标题
        PPrBase.PStyle style = new PPrBase.PStyle();
        style.setVal("Heading" + hlevel);
        ppr.setPStyle(style);

        p.setPPr( ppr );

        // Create and add <w:numPr>
        PPrBase.NumPr numPr =  factory.createPPrBaseNumPr();
        ppr.setNumPr(numPr);

        // The <w:ilvl> element
        PPrBase.NumPr.Ilvl ilvlElement = factory.createPPrBaseNumPrIlvl();
        numPr.setIlvl(ilvlElement);
        ilvlElement.setVal(BigInteger.valueOf(ilvl));

        // The <w:numId> element
        PPrBase.NumPr.NumId numIdElement = factory.createPPrBaseNumPrNumId();
        numPr.setNumId(numIdElement);
        numIdElement.setVal(BigInteger.valueOf(numId));

        return p;

    }
}
